package net.vsame.url2sql.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.vsame.url2sql.helper.Url2SqlContext;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.render.Render;
import net.vsame.url2sql.url.impl.UrlConfig;
import net.vsame.url2sql.url.impl.UrlMapping;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>好了歌(王立平)</p>
 * 世人都晓神仙好<br/>
 * 唯有功名忘不了<br/>
 * 古今将相在何方<br/>
 * 荒冢一堆草没了<br/>
 * <br/>
 * 世人都晓神仙好<br/>
 * 只有金银忘不了<br/>
 * 终朝只恨聚无多<br/>
 * 及到多时眼闭了<br/>
 */
public class Url2SqlFilter implements Filter {
	
	private static Log LOG = LogFactory.getLog(Url2SqlFilter.class);
	private static String encoding = "utf-8";
	private UrlMapping mapping;

    public Url2SqlFilter() {
    }


    @Override
	public void doFilter(ServletRequest _req, ServletResponse _resp, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) _req;
		HttpServletResponse response = (HttpServletResponse) _resp;
		// 设置编码
		request.setCharacterEncoding(encoding);
		response.setCharacterEncoding(encoding);
		
		//处理请求URL
		String requestURI = request.getRequestURI().substring(request.getContextPath().length());
		String[] urlNodes = resolveUrl(requestURI);
		
		if(urlNodes == null){
			chain.doFilter(request, response);
			return ;
		}
		
		//寻找Render
		Render render = mapping.findRender(urlNodes[1]);
		if(render == null) {//没有对应视图
			chain.doFilter(request, response);
			return ;
		}
		
		try{
			WebHelper.init(request, response);
			
			Url2SqlContext c = getContext(urlNodes);
			
			if(c != null) {
				c.setRender(render);
				
				//调用对应Action
				UrlMapping.getMapping().invoke();
				
				//优先用户设置的视图, 如果用户设置为NULL，则使用默认视图
				if(c.getRender() != null){
					render = c.getRender();
				}
				
			}
			
			if(render.getEncoding() == null){
				render.setEncoding(encoding);//优先用户设置的编码, 如果用户设置为NULL，则使用默认编码
			}
			render.setContext(request, response).render();
			
		}finally{
			WebHelper.remove();
		}
	}
	
	/**
	 * 分解URL
	 * @param url
	 * @return [path, extensionName]
	 */
	private static String[] resolveUrl(String url) {
		if(url == null) {
			return null;
		}
		int index = url.lastIndexOf(".");
		if(index == -1) {
			return null;
		}
		return new String[]{url.substring(0, index), url.substring(index+1)};
	}
	
	private Url2SqlContext getContext(String[] urlNodes){
		//寻找Action
		UrlConfig urlConfig = mapping.getConfig(urlNodes[0]);
		if(urlConfig == null){
			return null; //没有对应Action
		}
		
		//创建上下文
		Url2SqlContext context = WebHelper.getContext();
		context.setRequestUrl(urlNodes[0]);
		context.setExtensionName(urlNodes[1]);
		context.setUrlConfig(urlConfig);
		return context;
	}
	
	@Override
	public void init(FilterConfig config) throws ServletException {
		encoding = config.getInitParameter("encoding");
		// 默认编码为UTF-8
		if (encoding == null || "".equals(encoding)) {
			encoding = "UTF-8";
		}
		LOG.info("url2sql core init. encoding:" + encoding);
		
		mapping = UrlMapping.getMapping();
		mapping.reload(config.getServletContext()); 
	}
	
	@Override
	public void destroy() {
		mapping.destroy();
	}

}
